package com.example.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.demo.domin.dto.UserDTO;
import com.example.demo.domin.vo.UserVO;
import com.example.demo.util.JwtUtil;
import com.example.demo.domin.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.security.UserAuthentication;
import com.example.demo.service.UserService;
import com.example.demo.util.RedisUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.http.codec.cbor.Jackson2CborDecoder;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Resource
    AuthenticationManager authenticationManager;

    @Resource
    RedisUtil redisUtil;

    private static final String USER_LIST_KEY="users";

    @Override
    public void signUpUser(UserDTO user) {
        User insertUser = new User();
        BeanUtils.copyProperties(user,insertUser);
        insertUser.setPassword(bCryptPasswordEncoder.encode(insertUser.getPassword()));
        insertUser.setNickname(UUID.randomUUID().toString());
        insertUser.setCreateBy(user.getUsername());
        insertUser.setUpdateBy(user.getUsername());
        userMapper.insertUser(insertUser);
    }

    @Override
    public String login(UserDTO userDTO) {
        UserAuthentication authentication = new UserAuthentication(userDTO.getPassword(),userDTO.getUsername());
        UserAuthentication authenticate =(UserAuthentication) authenticationManager.authenticate(authentication);
        String token="";
        if (authenticate!=null){
            try {
                userDTO.setUserId(authenticate.getUserId());
                token=JwtUtil.getToken(userDTO);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        return token;
    }

    @Override
    public List<UserVO> getUserList() {
        if (redisUtil.hasKey(USER_LIST_KEY)){
            List<UserVO> value = (List<UserVO>) redisUtil.getCacheValue(USER_LIST_KEY);
                return value;
        }
        List<UserVO> list = userMapper.getUserList();
        redisUtil.cache(USER_LIST_KEY,list);
        return list;
    }
}
